/*
https://github.com/niemaattarian/Thompsons-Construction-on-NFAs
https://github.com/tjujingzong/TJU-C--compiler/
*/
#ifndef __NFA_H_
#define __NFA_H_
#include <vector>
#include <string>
#include <set>
#include <stdexcept>
#include <unordered_map>
#include <stack>
#include <queue>
#include "debug.h"

using namespace std;
enum TokenType
{
    FLOAT,
    INT,
    IDN,
    OP,
    SE
};

struct Pattern
{
    TokenType type;
    std::string regex;
};

// 状态和 NFA 定义
struct State
{
    std::string label;
    State *edge1;
    State *edge2;
    int id;
    State() : label(""), edge1(nullptr), edge2(nullptr), id(-1) {}
};

struct NFA
{
    TokenType type;
    State *initial;
    State *accept;
    NFA(State *s, State *a) : initial(s), accept(a) {}
};

std::vector<std::string> tokenize(const std::string &infix);
std::vector<std::string> addConcat(const std::vector<std::string> &tokens);
std::vector<std::string> shunt(const std::string &infix);
NFA *compile(TokenType type, const std::vector<std::string> &postfix);
NFA *merge_nfas(std::stack<NFA *> &nfaLists);
std::set<State *> epsilonClosure(std::set<State *> &states);
std::set<State *> move(std::set<State *> &states, const std::string &token);

#endif